// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
 *******************************************************************************
 * Copyright (C) 1996-2010, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */
package com.ibm.icu.dev.test.rbbi;

import com.ibm.icu.dev.test.CoreTestFmwk;
import com.ibm.icu.text.BreakIterator;
import java.text.CharacterIterator;
import java.util.Arrays;
import java.util.Locale;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

@RunWith(JUnit4.class)
public class BreakIteratorRegTest extends CoreTestFmwk {
    @Test
    public void TestRegUnreg() {
        Locale thailand_locale = new Locale("th", "TH", "");
        Locale foo_locale = new Locale("fu", "FU", "FOO");
        BreakIterator jwbi = BreakIterator.getWordInstance(Locale.JAPAN);
        BreakIterator uwbi = BreakIterator.getWordInstance(Locale.US);
        BreakIterator usbi = BreakIterator.getSentenceInstance(Locale.US);
        BreakIterator twbi = BreakIterator.getWordInstance(thailand_locale);
        BreakIterator rwbi = BreakIterator.getWordInstance(new Locale("", "", ""));

        BreakIterator sbi = usbi.clone();
        // todo: this will cause the test to fail, no way to set a breakiterator to null text so
        // can't fix yet.
        // String text = "This is some test, by golly. Boy, they don't make tests like they used to,
        // do they?  This here test ain't worth $2.50.  Nope.";
        // sbi.setText(text);

        assertTrue(!BreakIterator.unregister(""), "unregister before register"); // coverage

        Object key0 =
                BreakIterator.registerInstance(twbi.clone(), foo_locale, BreakIterator.KIND_WORD);
        Object key1 = BreakIterator.registerInstance(sbi, Locale.US, BreakIterator.KIND_WORD);
        Object key2 =
                BreakIterator.registerInstance(twbi.clone(), Locale.US, BreakIterator.KIND_WORD);

        {
            BreakIterator test0 = BreakIterator.getWordInstance(Locale.JAPAN);
            BreakIterator test1 = BreakIterator.getWordInstance(Locale.US);
            BreakIterator test2 = BreakIterator.getSentenceInstance(Locale.US);
            BreakIterator test3 = BreakIterator.getWordInstance(thailand_locale);
            BreakIterator test4 = BreakIterator.getWordInstance(foo_locale);

            assertEqual(test0, jwbi, "japan word == japan word");
            assertEqual(test1, twbi, "us word == thai word");
            assertEqual(test2, usbi, "us sentence == us sentence");
            assertEqual(test3, twbi, "thai word == thai word");
            assertEqual(test4, twbi, "foo word == thai word");
        }

        // Locale[] locales = BreakIterator.getAvailableLocales();

        assertTrue(BreakIterator.unregister(key2), "unregister us word (thai word)");
        assertTrue(!BreakIterator.unregister(key2), "unregister second time");
        boolean error = false;
        try {
            BreakIterator.unregister(null);
        } catch (IllegalArgumentException e) {
            error = true;
        }

        assertTrue(error, "unregister null");

        {
            CharacterIterator sci = BreakIterator.getWordInstance(Locale.US).getText();
            int len = sci.getEndIndex() - sci.getBeginIndex();
            assertEqual(len, 0, "us word text: " + getString(sci));
        }

        assertTrue(
                Arrays.asList(BreakIterator.getAvailableLocales()).contains(foo_locale),
                "foo_locale");
        assertTrue(BreakIterator.unregister(key0), "unregister foo word (thai word)");
        assertTrue(
                !Arrays.asList(BreakIterator.getAvailableLocales()).contains(foo_locale),
                "no foo_locale");
        assertEqual(BreakIterator.getWordInstance(Locale.US), usbi, "us word == us sentence");

        assertTrue(BreakIterator.unregister(key1), "unregister us word (us sentence)");
        {
            BreakIterator test0 = BreakIterator.getWordInstance(Locale.JAPAN);
            BreakIterator test1 = BreakIterator.getWordInstance(Locale.US);
            BreakIterator test2 = BreakIterator.getSentenceInstance(Locale.US);
            BreakIterator test3 = BreakIterator.getWordInstance(thailand_locale);
            BreakIterator test4 = BreakIterator.getWordInstance(foo_locale);

            assertEqual(test0, jwbi, "japanese word break");
            assertEqual(test1, uwbi, "us sentence-word break");
            assertEqual(test2, usbi, "us sentence break");
            assertEqual(test3, twbi, "thai word break");
            assertEqual(test4, rwbi, "root word break");

            CharacterIterator sci = test1.getText();
            int len = sci.getEndIndex() - sci.getBeginIndex();
            assertEqual(len, 0, "us sentence-word break text: " + getString(sci));
        }
    }

    private void assertEqual(Object lhs, Object rhs, String msg) {
        msg(msg, lhs.equals(rhs) ? LOG : ERR, true, true);
    }

    private void assertEqual(int lhs, int rhs, String msg) {
        msg(msg, lhs == rhs ? LOG : ERR, true, true);
    }

    private void assertTrue(boolean arg, String msg) {
        msg(msg, arg ? LOG : ERR, true, true);
    }

    private static String getString(CharacterIterator ci) {
        StringBuffer buf = new StringBuffer(ci.getEndIndex() - ci.getBeginIndex() + 2);
        buf.append("'");
        for (char c = ci.first(); c != CharacterIterator.DONE; c = ci.next()) {
            buf.append(c);
        }
        buf.append("'");
        return buf.toString();
    }
}
